﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Xml;
using System.Net.Sockets;


namespace WindowsFormsApplication3
{
    class Topic
    {
        private String topicNumber;

        public String title;
        public String link;
        public String description;
        public DateTime pubDate;
        public Boolean update;

        private Topic(String topicNumber)
        {
            this.title = null;
            this.description = null;
            this.link = null;
            this.update = false;

            this.topicNumber = topicNumber;
            this.upDate();
        }

        public String getDateTime()
        {
            TimeSpan ts = DateTime.Now - this.pubDate;

            String timespan = "";
            if (ts.Days > 0)
                timespan += ts.Days.ToString("0") + " д. ";
            if (ts.Hours > 0)
                timespan += ts.Hours.ToString("00") +":";
            timespan += ts.Minutes.ToString("00");

            return this.pubDate.ToString("d MMM HH:MM") + " (" + timespan + ")";
        }

        public void upDate()
        {
            String host = "rutrch.prostudent.org.ru";
            Int32 port = 80;

            String XmlData = SocketSendReceive(host, port, this.topicNumber);
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(XmlData);
            XmlNode item = xmlDoc.ChildNodes[1].ChildNodes[0];

            DateTime newDateTime = DateTime.Parse(item.ChildNodes[8].ChildNodes[5].InnerText);
            newDateTime = newDateTime.AddHours(4.0d);
            if (DateTime.Compare(this.pubDate, newDateTime) < 0 || (this.title == null && this.link == null && this.description == null))
            {
                this.title = item.ChildNodes[8].ChildNodes[0].InnerText;
                this.link = item.ChildNodes[8].ChildNodes[1].InnerText;
                this.description = item.ChildNodes[8].ChildNodes[2].InnerText;
                this.pubDate = newDateTime;
                this.update = true;

            }

        }

        private static Socket ConnectSocket(String server, Int32 port)
        {
            Socket s = null;
            IPHostEntry hostEntry = null;

            try
            {
                // Get host related information.
                hostEntry = Dns.GetHostEntry(server);

                // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
                // an exception that occurs when the host IP Address is not compatible with the address family
                // (typical in the IPv6 case).

                foreach (IPAddress address in hostEntry.AddressList)
                {
                    IPEndPoint ipe = new IPEndPoint(address, port);
                    Socket tempSocket =
                        new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                    tempSocket.Connect(ipe);

                    if (tempSocket.Connected)
                    {
                        s = tempSocket;
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }
            }
            catch (IOException e)
            {
                return null;
            }

            return s;
        }

        // This method requests the home page content for the specified server.
        private static string SocketSendReceive(String server, Int32 port, String topicNumber)
        {
            String request = "GET /topic/" + topicNumber + " HTTP/1.1\r\n" +
                                "Host: " + server + "\r\n" +
                                "Connection: Close\r\n\r\n";

            Byte[] bytesSent = Encoding.ASCII.GetBytes(request);
            Byte[] bytesReceived = new Byte[10000];

            Socket s = ConnectSocket(server, port);

            if (s == null)
                return ("Connection failed");

            s.Send(bytesSent, bytesSent.Length, 0);

            Int32 bytes = 0;
            String page = "";

            bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
            page = page + Encoding.UTF8.GetString(bytesReceived, 0, bytes);

            String[] stringSeparators = new String[] { "\r\n\r\n" };
            String[] tmp = page.Split(stringSeparators, StringSplitOptions.None);
            stringSeparators = new String[] { "\r\n" };
            tmp = tmp[1].Split(stringSeparators, StringSplitOptions.None);
            
            return tmp[1];
        }
        
        public static Topic[] RequestTopics(String[] topicsNumbers)
        {
            Topic[] Out = new Topic[topicsNumbers.Length];

            for (int i = 0; i < topicsNumbers.Length; i++)
            {
                Out[i] = new Topic(topicsNumbers[i]);
            }

            return Out;
        }
    }
}
